﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows;
using System.Linq;
using OfficeOpenXml;
using System.Dynamic;
using System.Text.Json;

namespace ToolExcelPub
{
    public static partial class XTool
    {
        public static void OutPages()
        {
            ShowInfo("OutPages!");

            foreach (var page in DictPages.Values)
            {
                OutPage(page);
            }
        }
        public static void OutPage(XPageInfo page)
        {
            Dictionary<object, dynamic> dictpServer = new Dictionary<object, dynamic>();
            Dictionary<object, dynamic> dictpClient = new Dictionary<object, dynamic>();

            foreach (var listrowvalue in page.ListValue)
            {
                dynamic pServer = new ExpandoObject();
                dynamic pClient = new ExpandoObject();
                for (int iii = 0; iii < page.Head.Count; iii++)
                {
                    var head = page.Head[iii];
                    if (head == "") { continue; }

                    var value = GetEnumValue(page.HeadEnum[iii], listrowvalue[iii]);
                    //服务器
                    {
                        EditRowData(page.TypeServer[iii], head, value, ref pServer);
                    }
                    //客户端
                    {
                        EditRowData(page.TypeClient[iii], head, value, ref pClient);
                    }
                }
                dictpServer[listrowvalue[0]] = pServer;
                dictpClient[listrowvalue[0]] = pClient;
            }
            if (page.HasType(EToolFileType.服务器))
            {
                ToolGlobal.WriteNewFile($"{PathJsonServer}\\{page.Name}.json", JsonSerializer.Serialize(dictpServer, JsonOpt));
            }
            if (page.HasType(EToolFileType.客户端))
            {
                ToolGlobal.WriteNewFile($"{PathJsonClient}\\{page.Name}.json", JsonSerializer.Serialize(dictpClient, JsonOpt));
            }
        }
        public static object GetDataObject(string type, string value)
        {
            return type switch
            {
                "bool" => value.ToLower().ToBool(),
                "int" => value.ToInt(),
                "short" => value.ToShort(),
                "long" => value.ToLong(),
                "float" => value.ToFloat(),
                "double" => value.ToDouble(),
                _ => value,
            };
        }
        public static void EditRowData(string type, string head, string value, ref dynamic p)
        {
            if (type != "")
            {
                switch (type)
                {
                    case "bool":
                    case "int":
                    case "short":
                    case "long":
                    case "float":
                    case "double":
                        ((IDictionary<string, object>)p).Add(head, GetDataObject(type, value));
                        break;
                    //case "bool":
                    //    ((IDictionary<string, object>)p).Add(head, value.ToLower().ToBool());
                    //    break;
                    //case "int":
                    //    ((IDictionary<string, object>)p).Add(head, value.ToInt());
                    //    break;
                    //case "long":
                    //    ((IDictionary<string, object>)p).Add(head, value.ToLong());
                    //    break;
                    //case "float":
                    //    ((IDictionary<string, object>)p).Add(head, value.ToFloat());
                    //    break;
                    //case "double":
                    //    ((IDictionary<string, object>)p).Add(head, value.ToDouble());
                    //    break;
                    case "List<string>":
                        ((IDictionary<string, object>)p).Add(head, value.ToListString());
                        break;
                    case "List<List<string>>":
                        ((IDictionary<string, object>)p).Add(head, value.ToListListString());
                        break;
                    case "List<int>":
                        ((IDictionary<string, object>)p).Add(head, value.ToListInt());
                        break;
                    case "List<List<int>>":
                        ((IDictionary<string, object>)p).Add(head, value.ToListListInt());
                        break;
                    case "List<float>":
                        ((IDictionary<string, object>)p).Add(head, value.ToListFloat());
                        break;
                    case "List<List<float>>":
                        ((IDictionary<string, object>)p).Add(head, value.ToListListFloat());
                        break;
                    case "List<double>":
                        ((IDictionary<string, object>)p).Add(head, value.ToListDouble());
                        break;
                    case "List<List<double>>":
                        ((IDictionary<string, object>)p).Add(head, value.ToListListDouble());
                        break;
                    case "Dictionary<string,string>":
                    case "Dictionary<string, string>":
                        ((IDictionary<string, object>)p).Add(head, value.ToDictionaryString());
                        break;
                    case "Dictionary<int,int>":
                    case "Dictionary<int, int>":
                        ((IDictionary<string, object>)p).Add(head, value.ToDictionaryInt());
                        break;
                    case "Dictionary<string,int>":
                    case "Dictionary<string, int>":
                        ((IDictionary<string, object>)p).Add(head, value.ToDictionaryStringInt());
                        break;
                    //自定义类
                    case string _ when (DictXPclassInfo.TryGetValue(type, out var pclassinfo)):
                        {
                            var list = value.ToListString();
                            dynamic pnode = new ExpandoObject();
                            for (int i = 0; i < pclassinfo.ListNode.Count; i++)
                            {
                                ((IDictionary<string, object>)pnode).Add(pclassinfo.ListNode[i][1]
                                    , GetDataObject(pclassinfo.ListNode[i][0], list[i]));
                            }
                            ((IDictionary<string, object>)p).Add(head, pnode);
                        }
                        break;
                    //自定义类列表
                    case string _ when (type.StartsWith("List<")):
                        {
                            var pclassname = type.GetMidStr("List<", ">");
                            if (DictXPclassInfo.TryGetValue(pclassname, out var pclassinfo))
                            {
                                var list = value.ToListListString();
                                List<dynamic> plist = new();
                                foreach (var itemlist in list)
                                {
                                    dynamic pnode = new ExpandoObject();
                                    for (int i = 0; i < pclassinfo.ListNode.Count; i++)
                                    {
                                        ((IDictionary<string, object>)pnode).Add(pclassinfo.ListNode[i][1]
                                            , GetDataObject(pclassinfo.ListNode[i][0], itemlist[i]));
                                    }
                                    plist.Add(pnode);
                                }
                                ((IDictionary<string, object>)p).Add(head, plist);
                            }
                        }
                        break;
                    default:
                        {
                            //if (DictXPclassInfo.TryGetValue(type, out var pclassinfo))
                            //{
                            //    var list = value.ToListListString();
                            //    List<dynamic> plist = new();
                            //    foreach (var itemlist in list)
                            //    {
                            //        dynamic pnode = new ExpandoObject();
                            //        for (int i = 0; i < pclassinfo.ListNode.Count; i++)
                            //        {
                            //            ((IDictionary<string, object>)pnode).Add(pclassinfo.ListNode[i][1], itemlist[i]);
                            //        }
                            //        plist.Add(pnode);
                            //    }
                            //    ((IDictionary<string, object>)p).Add(head, plist);
                            //}
                            //else
                            {
                                ((IDictionary<string, object>)p).Add(head, value);
                            }
                        }
                        break;
                }
            }
        }
        
    }
}
